import axios from "axios";
import { ElMessage } from "element-plus";

// 创建axios实例
const service = axios.create({
  baseURL: "http://localhost:8080/api", // API的基础URL
  timeout: 30000, // 默认请求超时时间，从15秒增加到30秒
  headers: {
    "Content-Type": "application/json",
  },
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 使用统一的令牌
    const token = localStorage.getItem("token");

    // 如果有令牌，添加到请求头中
    if (token) {
      config.headers["Authorization"] = `Bearer ${token}`;
    }
    
    // 对AI聊天相关请求设置更长的超时时间
    if (config.url && (
        config.url.includes("/ai-chat/messages") || 
        config.url.includes("/public/ai-chat/messages")
      )) {
      // 为AI相关请求设置120秒超时，足够大模型生成回复
      config.timeout = 180000; // 120秒
      console.log(`🕒 为AI请求设置更长超时: ${config.url}, timeout=${config.timeout}ms`);
    }
    
    return config;
  },
  (error) => {
    console.log("请求拦截器错误：", error);
    return Promise.reject(error);
  },
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // 对于二进制数据，直接返回
    if (response.config.responseType === 'blob' || response.config.responseType === 'arraybuffer') {
      return response;
    }

    const res = response.data;
    
    // 添加调试日志查看响应格式
    console.log("axios响应数据格式:", res);

    // 处理标准API响应格式（带code字段）
    if (res && res.code !== undefined) {
      if (res.code !== 200) {
        // 处理特定错误码
        if (res.code === 401) {
          // 认证错误时不自动清除token，避免开发时频繁登录
          console.warn("认证错误 (401)，但在开发环境中不自动清除token");
          // localStorage.removeItem("token"); // 注释掉自动清除token的代码
        }
        return Promise.reject(new Error(res.message || "发生错误"));
      } else {
        // 成功响应，返回data字段（如果有）或者整个响应数据
        return res.data !== undefined ? res : res;
      }
    }

    // 对于非标准格式响应，直接返回数据
    return res;
  },
  (error) => {
    console.log("响应拦截器错误：", error);

    // 检查是否是Redis连接错误
    if (error.response && error.response.status === 401 && 
        error.response.data && error.response.data.message && 
        typeof error.response.data.message === 'string' && 
        error.response.data.message.includes("Redis")) {
      console.warn("检测到Redis连接错误，尝试使用本地令牌继续操作");
      // 返回一个自定义错误，在组件中可以特殊处理这种情况
      return Promise.reject(new Error("Redis连接错误，请稍后重试"));
    }

    // 根据错误类型构造适当的错误对象
    if (error.response) {
      // 服务器返回了错误状态码
      const status = error.response.status;
      const data = error.response.data;
      
      // 处理认证错误
      if (status === 401 || status === 403) {
        // 在开发环境中，不自动清除token，而是打印详细错误，方便调试
        console.warn("收到401/403错误，详细信息:", {
          status,
          url: error.config.url,
          method: error.config.method,
          data: error.config.data,
          responseData: data
        });
        
        // 判断是否自动清除token（开发环境可以考虑不清除）
        // 在生产环境中取消这个注释
        // localStorage.removeItem("token");
        
        return Promise.reject(new Error(data?.message || "未提供有效的认证凭证"));
      } else if (status === 400) {
        // 处理参数验证错误
        console.warn("收到400错误，可能是参数验证失败:", {
          url: error.config.url,
          method: error.config.method,
          data: error.config.data,
          responseData: data
        });
        
        // 检查是否有字段验证错误信息
        if (data && data.message) {
          return Promise.reject(new Error(data.message));
        }
        return Promise.reject(new Error("请求参数验证失败"));
      } else if (status === 404) {
        return Promise.reject(new Error("请求的资源不存在"));
      } else {
        return Promise.reject(new Error(data?.message || "服务器错误，请稍后重试"));
      }
    } else if (error.request) {
      // 请求已发送但未收到响应
      return Promise.reject(new Error("网络错误，请检查您的网络连接"));
    } else {
      // 请求配置出错
      return Promise.reject(new Error("请求配置错误"));
    }
  },
);

// 过滤调试信息的辅助函数
const filterDebugText = (text) => {
  // 过滤掉"正在连接AI服务..."等调试信息
  if (!text) return text;
  
  const debugPatterns = [
    /正在连接AI服务.*/g,
    /连接中.*/g,
    /初始化连接.*/g
  ];
  
  let filteredText = text;
  for (const pattern of debugPatterns) {
    filteredText = filteredText.replace(pattern, '');
  }
  
  return filteredText;
};

// 修复字符重复问题的函数
const fixRepeatedCharacters = (text) => {
  if (!text) return text;
  
  // 检测并修复字符级别的重复模式
  // 例如："欢迎欢迎来到来到贵贵港港！！"
  
  // 首先尝试简单的相邻字符去重
  let result = '';
  let lastChar = '';
  let lastTwoChars = '';
  let lastThreeChars = '';
  
  const chars = Array.from(text); // 确保正确处理UTF-8字符
  
  for (let i = 0; i < chars.length; i++) {
    const currentChar = chars[i];
    
    // 检查是否有单字符重复（如：贵贵）
    if (currentChar === lastChar && i > 0 && chars[i-1] === chars[i]) {
      continue;
    }
    
    // 检查是否有两字符重复（如：欢迎欢迎）
    if (i >= 3 && lastTwoChars === chars[i-1] + currentChar) {
      continue;
    }
    
    // 检查是否有三字符重复（如：你好吗你好吗）
    if (i >= 5 && lastThreeChars === chars[i-2] + chars[i-1] + currentChar) {
      continue;
    }
    
    // 更新最近的字符记录
    lastThreeChars = lastTwoChars + currentChar;
    lastTwoChars = lastChar + currentChar;
    lastChar = currentChar;
    
    // 添加到结果
    result += currentChar;
  }
  
  // 匹配常见的重复模式并修复
  const patterns = [
    // 中文标点符号重复
    { pattern: /！！+/g, replace: '！' },
    { pattern: /。。+/g, replace: '。' },
    { pattern: /，，+/g, replace: '，' },
    { pattern: /：：+/g, replace: '：' },
    // 表情符号重复
    { pattern: /😊😊+/g, replace: '😊' },
    { pattern: /🏛🏛+/g, replace: '🏛' },
    { pattern: /️️+/g, replace: '️' },
    { pattern: /🍜🍜+/g, replace: '🍜' },
    { pattern: /⛩⛩+/g, replace: '⛩' },
    { pattern: /🌉🌉+/g, replace: '🌉' },
    { pattern: /⛰⛰+/g, replace: '⛰' },
    { pattern: /🍲🍲+/g, replace: '🍲' },
    { pattern: /🌳🌳+/g, replace: '🌳' },
    { pattern: /♨♨+/g, replace: '♨' },
    { pattern: /🚣🚣+/g, replace: '🚣' },
    { pattern: /‍‍+/g, replace: '‍' },
    { pattern: /♀♀+/g, replace: '♀' },
    { pattern: /🍵🍵+/g, replace: '🍵' },
    { pattern: /🛍🛍+/g, replace: '🛍' },
    { pattern: /☀☀+/g, replace: '☀' },
    { pattern: /🚕🚕+/g, replace: '🚕' },
    { pattern: /🍁🍁+/g, replace: '🍁' },
    { pattern: /😄😄+/g, replace: '😄' },
    // 常见的格式标记重复
    { pattern: /\*\*\*\*+/g, replace: '**' },
    { pattern: /--+/g, replace: '--' },
  ];
  
  let fixedText = result;
  for (const { pattern, replace } of patterns) {
    fixedText = fixedText.replace(pattern, replace);
  }
  
  return fixedText;
};

/**
 * 创建SSE连接用于流式接收数据
 * @param {string} url - 请求URL
 * @param {Object} options - 配置选项
 * @param {Function} onMessage - 接收消息的回调，参数为(data, eventType)
 * @param {Function} onError - 错误处理回调
 * @param {Function} onClose - 连接关闭回调
 * @returns {EventSource} EventSource实例
 */
export const createSSEConnection = (url, options = {}, onMessage, onError, onClose) => {
  // 添加token认证
  const token = localStorage.getItem("token");
  const baseUrl = noTimeoutService.defaults.baseURL || service.defaults.baseURL;
  const fullUrl = new URL(url.startsWith("http") ? url : `${baseUrl}${url}`);
  
  // 添加传入的参数
  if (options.params) {
    Object.keys(options.params).forEach(key => {
      fullUrl.searchParams.append(key, options.params[key]);
    });
  }
  
  // 添加token
  if (token) {
    fullUrl.searchParams.append("token", token);
  }
  
  console.log(`📡 创建SSE连接: ${fullUrl.toString()}`);
  
  // 创建EventSource连接
  const eventSource = new EventSource(fullUrl.toString());
  
  // 用于累积收到的内容
  let accumulatedContent = "";
  let isClosing = false;
  let lastMessageLength = 0; // 记录上次消息长度，用于检测重置
  let totalMessages = 0; // 记录收到的消息总数，用于判断流的阶段
  let normalEndReceived = false; // 标记是否已收到正常结束事件
  
  // 判断是否为增量更新的辅助函数
  const isIncrementalUpdate = (newContent) => {
    if (!newContent) return false;
    
    // 如果新内容比旧内容短，可能是服务器重新开始发送（但也可能是部分单字符增量更新）
    if (newContent.length < accumulatedContent.length - 5) {
      return false;
    }
    
    // 如果新内容与当前内容一样，不是增量
    if (newContent === accumulatedContent) {
      return false;
    }
    
    // 如果新内容包含旧内容的末尾，可能是增量更新
    const lastChunk = accumulatedContent.slice(-20); // 取最后20个字符比较
    return newContent.includes(lastChunk);
  };
  
  // 确定如何处理新内容的辅助函数
  const processNewContent = (newContent) => {
    // 如果是首次接收消息或首条正式消息，直接使用
    if (accumulatedContent === "" || totalMessages <= 2) {
      return newContent;
    }
    
    // 尝试智能判断是增量更新还是完整内容替换
    if (isIncrementalUpdate(newContent)) {
      // 是增量更新，找出新增部分
      // 尝试从后向前比较找出新增内容
      let i = 1;
      while (i <= Math.min(accumulatedContent.length, newContent.length)) {
        if (accumulatedContent.slice(-i) === newContent.slice(0, i)) {
          // 找到重叠部分，返回新增内容
          return accumulatedContent + newContent.slice(i);
        }
        i++;
      }
      
      // 如果无法找到精确重叠部分，尝试查找最近的空格作为分界点
      const lastSpaceIndex = newContent.lastIndexOf(" ");
      if (lastSpaceIndex > 0 && !accumulatedContent.endsWith(newContent.substring(0, lastSpaceIndex + 1))) {
        const incrementalPart = newContent.substring(lastSpaceIndex + 1);
        // 确保这部分确实是新增的
        if (!accumulatedContent.endsWith(incrementalPart)) {
          return accumulatedContent + incrementalPart;
        }
      }
      
      // 如果上述方法都失败，保守地返回新内容
      return newContent;
    } else {
      // 看起来是完整替换，但进行额外检查
      // 如果新内容长度突然减少很多，可能是服务器重置了消息
      if (newContent.length < accumulatedContent.length * 0.7) {
        return newContent; // 可能是新开始的内容，使用新内容
      }
      
      // 默认逻辑：如果消息单调增长，优先使用累积逻辑
      if (newContent.length >= lastMessageLength) {
        return newContent; // 使用服务器提供的最新完整内容
      } else {
        // 长度减少，但减少不多，可能是临时回退
        return accumulatedContent; // 保持当前累积内容不变
      }
    }
  };
  
  // 关闭连接的辅助函数
  const closeConnection = (gracefully = false) => {
    if (isClosing) return;
    isClosing = true;
    
    // 标记为正常结束，避免显示错误
    if (gracefully) {
      normalEndReceived = true;
    }
    
    // 延迟关闭，确保最后的数据显示完毕
    setTimeout(() => {
      console.log("关闭SSE连接");
      eventSource.close();
      onClose && onClose();
    }, gracefully ? 200 : 50); // 正常结束时给更多时间处理最后的消息
  };
  
  // 监听初始连接确认
  eventSource.addEventListener('init', (event) => {
    try {
      const data = JSON.parse(event.data);
      console.log('SSE连接已初始化:', data);
      totalMessages++; // 计数
      // 不将初始化事件传递给界面显示
    } catch (error) {
      console.error('解析init事件数据失败:', error);
    }
  });
  
  // 监听普通消息
  eventSource.addEventListener('message', (event) => {
    try {
      totalMessages++; // 增加消息计数
      const data = JSON.parse(event.data);
      
      // 处理内容更新
      if (data.content !== undefined) {
        // 过滤掉调试信息
        const filteredContent = filterDebugText(data.content);
        
        // 确定如何处理新内容 - 增量追加还是完整替换
        const processedContent = processNewContent(filteredContent);
        
        // 更新累积内容
        accumulatedContent = processedContent;
        
        // 更新最近消息长度
        lastMessageLength = accumulatedContent.length;
        
        // 修复字符重复问题
        const fixedContent = fixRepeatedCharacters(accumulatedContent);
        
        // 调用回调函数
        onMessage && onMessage({...data, content: fixedContent}, 'message');
      } else {
        // 如果没有content字段，仍然传递其他数据
        onMessage && onMessage(data, 'message');
      }
    } catch (error) {
      // 如果不是JSON格式，当作普通文本处理
      if (!isClosing && event.data) {
        totalMessages++; // 增加消息计数
        
        // 是否为字符串
        const textContent = typeof event.data === 'string' ? event.data : String(event.data);
        
        // 过滤掉调试信息
        const filteredText = filterDebugText(textContent);
        
        // 累加内容
        if (filteredText && filteredText.trim() && !accumulatedContent.endsWith(filteredText)) {
          accumulatedContent += filteredText;
          lastMessageLength = accumulatedContent.length;
        }
        
        // 修复字符重复问题
        const fixedText = fixRepeatedCharacters(accumulatedContent);
        
        if (fixedText.trim()) {
          // 传递累积内容
          onMessage && onMessage({content: fixedText}, 'message');
        }
      }
    }
  });
  
  // 监听思考过程
  eventSource.addEventListener('reasoning', (event) => {
    try {
      totalMessages++; // 增加消息计数
      const data = JSON.parse(event.data);
      onMessage && onMessage(data, 'reasoning');
    } catch (error) {
      // 如果不是JSON格式，将其作为纯文本处理
      if (!isClosing && event.data) {
        totalMessages++; // 增加消息计数
        
        // 获取文本内容
        const textContent = typeof event.data === 'string' ? event.data : String(event.data);
        
        // 过滤掉调试信息
        const filteredText = filterDebugText(textContent);
        
        if (filteredText && filteredText.trim()) {
          // 传递文本内容
          onMessage && onMessage({content: filteredText}, 'reasoning');
        }
      } else {
        console.error('解析reasoning事件数据失败:', error);
      }
    }
  });
  
  // 监听保持活跃
  eventSource.addEventListener('keepalive', (event) => {
    // 只记录日志，不发送到UI
    console.log('收到keepalive事件，保持连接活跃');
  });
  
  // 监听错误信息
  eventSource.addEventListener('error', (event) => {
    try {
      totalMessages++; // 增加消息计数
      let errorData;
      try {
        errorData = JSON.parse(event.data);
      } catch (e) {
        errorData = {message: event.data || '连接错误'};
      }
      
      console.error('SSE错误:', errorData);
      onMessage && onMessage(errorData, 'error');
      
      // 关闭连接
      closeConnection(false);
    } catch (error) {
      console.error('处理error事件失败:', error);
      if (onError) {
        onError(error);
      }
    }
  });
  
  // 监听结束事件
  eventSource.addEventListener('end', (event) => {
    try {
      totalMessages++; // 增加消息计数
      let data = {finished: true};
      try {
        data = {...data, ...JSON.parse(event.data)};
      } catch (e) {
        // 如果不是JSON格式，使用默认end数据
      }
      
      console.log('SSE传输结束:', data);
      
      // 确保最后传递过滤后的内容
      const filteredContent = filterDebugText(accumulatedContent);
      const fixedContent = fixRepeatedCharacters(filteredContent);
      onMessage && onMessage({...data, content: fixedContent}, 'end');
      
      // 标记为正常结束
      normalEndReceived = true;
      
      // 关闭连接
      closeConnection(true);
    } catch (error) {
      console.error('处理end事件失败:', error);
    }
  });
  
  // 处理通用错误
  eventSource.onerror = (error) => {
    // 如果已经收到正常结束事件，不显示错误
    if (normalEndReceived) {
      console.log('SSE连接已正常关闭，忽略后续错误事件');
      return;
    }
    
    console.error('SSE连接错误:', error);
    if (onError) {
      onError(error);
    }
    closeConnection(false);
  };
  
  return {
    close: () => closeConnection(false),
    eventSource
  };
};

// 创建无超时限制的axios实例，用于流式请求
export const noTimeoutService = axios.create({
  baseURL: "http://localhost:8080/api",
  timeout: 0, // 无超时限制
  headers: {
    "Content-Type": "application/json",
  },
});

// 为无超时实例添加相同的拦截器
noTimeoutService.interceptors.request.use(
  (config) => {
    // 使用统一的令牌
    const token = localStorage.getItem("token");
    // 如果有令牌，添加到请求头中
    if (token) {
      config.headers["Authorization"] = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    console.log("请求拦截器错误：", error);
    return Promise.reject(error);
  }
);

noTimeoutService.interceptors.response.use(
  (response) => {
    // 对于二进制数据，直接返回
    if (response.config.responseType === 'blob' || response.config.responseType === 'arraybuffer') {
      return response;
    }

    const res = response.data;
    
    // 处理标准API响应格式（带code字段）
    if (res && res.code !== undefined) {
      if (res.code !== 200) {
        // 处理特定错误码
        if (res.code === 401) {
          console.warn("认证错误 (401)，但在开发环境中不自动清除token");
        }
        return Promise.reject(new Error(res.message || "发生错误"));
      } else {
        // 成功响应，返回data字段（如果有）或者整个响应数据
        return res.data !== undefined ? res : res;
      }
    }

    // 对于非标准格式响应，直接返回数据
    return res;
  },
  (error) => {
    console.log("无超时服务响应拦截器错误：", error);
    return Promise.reject(new Error("网络错误，请重试"));
  }
);

export default service;
